package com.numberone.iotplatform.service.impl;

import com.numberone.iotplatform.dto.ScanStatus;
import com.numberone.iotplatform.dto.a_i_box.DeviceInfoDTO;
import com.numberone.iotplatform.entity.DiscoveredDevice;
import com.numberone.iotplatform.repository.DiscoveredDeviceRepository;
import com.numberone.iotplatform.service.AiBoxApiService;
import com.numberone.iotplatform.service.DeviceScanService;
import com.numberone.iotplatform.service.WebSocketMessagingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * DeviceScanService 接口的实现类。
 * 包含了异步扫描的核心业务逻辑。
 */
@Service
public class DeviceScanServiceImpl implements DeviceScanService {

    // 使用一个静态、线程安全的 Map 来存储所有扫描任务的状态
    // 静态意味着它在应用的整个生命周期中都存在
    public static final Map<String, ScanStatus> scanTasks = new ConcurrentHashMap<>();

    @Autowired
    private AiBoxApiService aiBoxApiService;

    @Autowired
    private WebSocketMessagingService webSocketMessagingService;

    @Autowired
    private DiscoveredDeviceRepository discoveredDeviceRepository;


    /**
     * 异步启动设备扫描任务。
     * 使用 @Async 注解，Spring 会在指定的 "taskExecutor" 线程池中执行此方法。
     * 所有代码已确认兼容 JDK 1.8。
     */
    @Override
    @Async("taskExecutor")
    public CompletableFuture<String> startScan(String taskId, String ipRange, int port, String username, String password) {
        String topic = "/topic/scan-progress/" + taskId;
        ScanStatus status = scanTasks.get(taskId);

        // 防御性编程：如果任务状态在启动前不存在，则不执行
        if (status == null) {
            System.err.println("Scan task " + taskId + " not found in map. Aborting.");
            return CompletableFuture.completedFuture("Task not found");
        }

        try {
            List<String> ipList = parseIpRange(ipRange);
            status.setTotal(ipList.size());
            status.setStatus("RUNNING");
            webSocketMessagingService.sendMessage(topic, status);

            for (int i = 0; i < ipList.size(); i++) {
                String ip = ipList.get(i);

                // 模拟扫描：20% 几率扫描成功
                if (Math.random() < 0.2) {
                    System.out.println(">>> Scan success! Found a valid device at IP: " + ip);

                    // 检查数据库中是否已存在该 IP 的待导入设备，避免重复
                    if (!discoveredDeviceRepository.findByIpAddressAndPort(ip, port).isPresent()) {
                        DiscoveredDevice discoveredDevice = new DiscoveredDevice();
                        discoveredDevice.setIpAddress(ip);
                        discoveredDevice.setPort(port);

                        // 模拟从设备获取型号
                        String model = Math.random() > 0.5 ? "XC-IVS-MOCK-8008-1U" : "XC-IVS-MOCK-8004-1U";
                        discoveredDevice.setModel(model);

                        discoveredDevice.setStatus("PENDING_IMPORT");
                        discoveredDevice.setScanTaskId(taskId);

                        // 保存到数据库
                        discoveredDeviceRepository.save(discoveredDevice);
                        status.incrementFoundCount();
                    }
                }

                status.setProgress(i + 1);
                webSocketMessagingService.sendMessage(topic, status);
                Thread.sleep(200); // 模拟延迟，让扫描过程更真实
            }
        } catch (InterruptedException e) {
            status.setStatus("FAILED");
            status.setError("Scan task was interrupted.");
            Thread.currentThread().interrupt(); // 重新设置中断状态
        } catch (Exception e) {
            status.setStatus("FAILED");
            status.setError("An unexpected error occurred during scan: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // 任务结束，更新最终状态并推送
            if (!"FAILED".equals(status.getStatus())) {
                status.setStatus("COMPLETED");
            }
            webSocketMessagingService.sendMessage(topic, status);
            System.out.println(">>> Scan task " + taskId + " finished with status: " + status.getStatus());
        }

        return CompletableFuture.completedFuture("Scan completed with status: " + status.getStatus());
    }

    @Override
    public ScanStatus getScanStatus(String taskId) {
        return scanTasks.get(taskId);
    }

    /**
     * 解析 IP 地址范围字符串。
     * 例如："192.168.1.1-254" -> ["192.168.1.1", "192.168.1.2", ..., "192.168.1.254"]
     * @param ipRange IP 范围字符串
     * @return IP 地址列表
     */
    private List<String> parseIpRange(String ipRange) {
        if (ipRange == null || ipRange.trim().isEmpty()) {
            return new ArrayList<>();
        }

        List<String> ips = new ArrayList<>();
        try {
            String[] parts = ipRange.split("-");
            if (parts.length != 2) {
                // 如果格式不正确，尝试看它是不是单个 IP
                if(isValidIp(parts[0])) ips.add(parts[0]);
                return ips;
            }

            String baseIp = parts[0].substring(0, parts[0].lastIndexOf('.') + 1);
            int start = Integer.parseInt(parts[0].substring(parts[0].lastIndexOf('.') + 1));
            int end = Integer.parseInt(parts[1]);

            if (start > end || start < 0 || end > 255) {
                throw new IllegalArgumentException("Invalid IP range values.");
            }

            for (int i = start; i <= end; i++) {
                ips.add(baseIp + i);
            }
        } catch (Exception e) {
            System.err.println("Failed to parse IP range '" + ipRange + "': " + e.getMessage());
            // 解析失败，返回空列表
            return new ArrayList<>();
        }
        return ips;
    }

    // 简单的 IP 格式验证
    private boolean isValidIp(String ip) {
        // (简单的实现，可以用更复杂的正则表达式)
        return ip != null && ip.matches("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$");
    }
}